package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.domain.BorrowRecord;
import com.example.domain.Book;
import com.example.domain.User;
import com.example.dto.ReturnRequestDTO;
import com.example.exception.BusinessException;
import com.example.mapper.BookCopyMapper;
import com.example.security.LoginUser;
import com.example.security.SecurityConfig;
import com.example.service.BorrowService;
import com.example.service.OperationLogService;
import com.example.service.BookCopyService;
import com.example.mapper.BorrowRecordMapper;
import com.example.mapper.BookMapper;
import com.example.mapper.UserMapper;
import com.example.dto.BorrowBookDTO;
import com.example.domain.BookCopy;
import com.example.util.Result;
import com.example.vo.BorrowRecordVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author HP
* @description 针对表【borrow_record】的数据库操作Service实现
* @createDate 2025-08-18 19:32:56
*/
@Service
public class BorrowServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord>
    implements BorrowService {

    @Resource
    private BorrowRecordMapper borrowRecordMapper;

    @Resource
    private BookMapper bookMapper;

    @Resource
    private OperationLogService operationLogService;

    @Resource
    private UserMapper userMapper;
    
    @Resource
    private BookCopyService bookCopyService;
    @Autowired
    private BookCopyMapper bookCopyMapper;
    @Autowired
    private SecurityConfig securityConfig;

    @Override
    public Result returnBook(ReturnRequestDTO returnRequestDTO) {

        // 检查借阅记录是否存在
        BorrowRecord borrowRecord = borrowRecordMapper.selectById(returnRequestDTO.getBorrowId());
        if (borrowRecord == null) {
            throw new BusinessException("借阅记录不存在");
        }
        // 检查借阅记录状态
        if (borrowRecord.getBorrowStatus() == 1) {
            throw new BusinessException("该借阅记录已完成归还");
        }

        // 获取相关信息用于日志
        User user = userMapper.selectById(borrowRecord.getUserId());
        Book book = bookMapper.selectById(borrowRecord.getBookCopyId());

        // 更新借阅记录
        borrowRecord.setActualReturnTime(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
        borrowRecord.setBorrowStatus(1); // 已归还

        int update = borrowRecordMapper.updateById(borrowRecord);
        if (update <= 0) {
            throw new BusinessException("归还失败");
        }

        // 更新图书状态
        // 简化处理，假设book_copy_id
        if (book != null) {
            BookCopy bookCopy = bookCopyMapper.selectById(borrowRecord.getBookCopyId());
            bookCopy.setBookCopyStatus(0); // 在馆
            int updateBookCopy = bookCopyMapper.updateById(bookCopy);
            if (updateBookCopy <= 0) {
                throw new BusinessException("归还失败");
            }
        }
        return Result.success();
    }

    @Override
    public List<BorrowRecord> getBorrowRecordsByUserId(Long userId) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }

        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        List<BorrowRecord> borrowRecords = borrowRecordMapper.selectList(queryWrapper);

        return borrowRecords;
    }

    @Override
    public List<BorrowRecordVO> getBorrowRecordsWithBookInfoByUserId(Long userId) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }

        // 查询用户的借阅记录
        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.orderByDesc("borrow_time"); // 按借阅时间倒序
        List<BorrowRecord> borrowRecords = borrowRecordMapper.selectList(queryWrapper);

        List<BorrowRecordVO> voList = new ArrayList<>();
        for (BorrowRecord borrowRecord : borrowRecords) {
            BorrowRecordVO vo = new BorrowRecordVO();
            
            // 复制基本信息
            BeanUtils.copyProperties(borrowRecord, vo);
            
            // 通过book_copy_id查询BookCopy获取book_id
            BookCopy bookCopy = bookCopyMapper.selectById(borrowRecord.getBookCopyId());
            if (bookCopy != null) {
                vo.setBookId(bookCopy.getBookId());
                
                // 通过book_id查询Book获取书名等信息
                Book book = bookMapper.selectById(bookCopy.getBookId());
                if (book != null) {
                    vo.setBookTitle(book.getTitle());
                    vo.setAuthor(book.getAuthor());
                    vo.setPublisher(book.getPublisher());
                }
            }
            
            // 设置借阅状态描述（在复制基本信息后调用）
            // vo.setBorrowStatusDesc(vo.getBorrowStatusDesc()); // 这行不需要，因为getBorrowStatusDesc()方法会根据borrowStatus自动计算
            
            // 计算是否逾期和逾期天数
            if (borrowRecord.getBorrowStatus() == 0 || borrowRecord.getBorrowStatus() == 2) {
                Date now = new Date();
                if (borrowRecord.getDueReturnTime().before(now)) {
                    vo.setOverdue(true);
                    long diffInMillies = now.getTime() - borrowRecord.getDueReturnTime().getTime();
                    long diffInDays = diffInMillies / (24 * 60 * 60 * 1000);
                    vo.setOverdueDays((int) diffInDays);
                } else {
                    vo.setOverdue(false);
                    vo.setOverdueDays(0);
                }
            } else {
                vo.setOverdue(false);
                vo.setOverdueDays(0);
            }
            
            voList.add(vo);
        }

        return voList;
    }

    @Override
    public List<BorrowRecord> getBorrowRecordsByBookId(Long bookId) {
        if (bookId == null) {
            throw new BusinessException("图书ID不能为空");
        }

        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_copy_id", bookId);
        List<BorrowRecord> borrowRecords = borrowRecordMapper.selectList(queryWrapper);

        return borrowRecords;
    }

    @Override
    public List<BorrowRecord> getOverdueBorrowRecords() {
        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("borrow_status", 1); // 借阅中
        // 转换 LocalDateTime 到 Date 进行比较
        queryWrapper.lt("due_return_time", Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant())); // 已过期
        List<BorrowRecord> overdueRecords = borrowRecordMapper.selectList(queryWrapper);

        return overdueRecords;
    }
    
    /**
     * 检查用户是否有逾期未还的图书
     * @param userId 用户ID
     * @return 是否有逾期图书
     */
    private boolean hasOverdueBooks(Long userId) {
        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("borrow_status", 1); // 借阅中
        queryWrapper.lt("due_return_time", Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant())); // 已过期
        return borrowRecordMapper.selectCount(queryWrapper) > 0;
    }
    
    /**
     * 获取用户当前借阅数量
     * @param userId 用户ID
     * @return 当前借阅数量
     */
    private int getCurrentBorrowCount(Long userId) {
        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("borrow_status", 0); // 借阅中
        return Math.toIntExact(borrowRecordMapper.selectCount(queryWrapper));
    }
    
    /**
     * 检查用户是否已借阅同一本书
     * @param userId 用户ID
     * @param bookId 图书ID
     * @return 是否已借阅
     */
    private boolean hasAlreadyBorrowed(Long userId, Long bookId) {
        QueryWrapper<BorrowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("book_copy_id", bookId);
        queryWrapper.eq("borrow_status", 1); // 借阅中
        return borrowRecordMapper.selectCount(queryWrapper) > 0;
    }
    
    @Override
    public boolean renewBook(Long borrowId, int days, Long operatorId, String operatorName, String ip) {
        if (borrowId == null || days <= 0) {
            throw new BusinessException("借阅记录ID不能为空，续借天数必须大于0");
        }
        
        // 检查借阅记录是否存在
        BorrowRecord borrowRecord = borrowRecordMapper.selectById(borrowId);
        if (borrowRecord == null) {
            throw new BusinessException("借阅记录不存在");
        }
        
        // 检查借阅记录状态
        if (borrowRecord.getBorrowStatus() != 1) {
            throw new BusinessException("该借阅记录不是借阅中状态，无法续借");
        }
        
        // 检查是否已经逾期
        Date now = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
        if (borrowRecord.getDueReturnTime().before(now)) {
            throw new BusinessException("该图书已逾期，无法续借，请先归还");
        }
        
        // 更新应还时间
        LocalDateTime newDueTime = borrowRecord.getDueReturnTime().toInstant()
            .atZone(ZoneId.systemDefault()).toLocalDateTime().plusDays(days);
        borrowRecord.setDueReturnTime(Date.from(newDueTime.atZone(ZoneId.systemDefault()).toInstant()));
        
        int result = borrowRecordMapper.updateById(borrowRecord);
        if (result <= 0) {
            throw new BusinessException("续借失败");
        }
        
        // 记录操作日志
        operationLogService.recordLog(operatorId, borrowId, 2,
            "续借图书，借阅记录ID: " + borrowId + "，续借天数: " + days + "天");
        
        return true;
    }
    
    @Override
    public int getUserCurrentBorrowCount(Long userId) {
        return getCurrentBorrowCount(userId);
    }
    
    @Override
    public String checkBorrowEligibility(Long userId, Long bookId) {
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            return "用户不存在";
        }
        
        // 检查图书是否存在
        BookCopy book = bookCopyMapper.selectById(bookId);
        if (book == null) {
            return "图书不存在";
        }
        
        // 检查图书状态
        if (book.getBookCopyStatus() != 1) {
            return "该图书当前不可借阅";
        }
        
        // 检查用户是否有逾期未还的图书
        if (hasOverdueBooks(userId)) {
            return "您有逾期未还的图书，请先归还后再借阅";
        }
        
        // 检查用户借阅数量限制
        if (getCurrentBorrowCount(userId) >= 3) {
            return "您已达到最大借阅数量限制（3本）";
        }
        
        // 检查用户是否已借阅同一本书
        if (hasAlreadyBorrowed(userId, bookId)) {
            return "您已借阅过这本书，请先归还后再借阅";
        }
        
        return "可以借阅";
    }

    
    @Override
    public Long getAvailableBookCopyId(Long bookId) {
        if (bookId == null) {
            return null;
        }
        
        // 查询该图书的可用副本（状态为0-在馆）
        QueryWrapper<BookCopy> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.eq("status", 0); // 在馆状态
        queryWrapper.last("LIMIT 1"); // 只取一个
        
        List<BookCopy> availableCopies = bookCopyService.list(queryWrapper);
        if (availableCopies.isEmpty()) {
            return null;
        }
        
        return availableCopies.get(0).getId();
    }

    @Override
    public Result borrowBook(BorrowBookDTO borrowBookDTO) {
        try {
            // 检查图书副本是否存在且可借阅
            BookCopy bookCopy = bookCopyService.getById(borrowBookDTO.getBookCopyId());
            if (bookCopy == null) {
                throw new BusinessException("图书副本不存在");
            }
            if (bookCopy.getBookCopyStatus() != 0) {
                throw new BusinessException("图书副本不可借阅");
            }
            // 获取用户
            LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            Long userId = loginUser.getId();

            // 检查用户借阅权限
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw new BusinessException("用户不存在");
            }
            
            // 检查用户是否有逾期未还的图书
            if (hasOverdueBooks(userId)) {
                throw new BusinessException("您有逾期未还的图书，请先归还后再借阅");
            }
            
            // 检查用户借阅数量限制（3本）
            int currentBorrowCount = getCurrentBorrowCount(userId);
            if (currentBorrowCount >= 3) {
                throw new BusinessException(String.format("您已达到最大借阅数量限制（3本），当前已借%d本", currentBorrowCount));
            }
            // 创建借阅记录
            BorrowRecord borrowRecord = new BorrowRecord();
            borrowRecord.setUserId(userId);
            borrowRecord.setBookCopyId(borrowBookDTO.getBookCopyId());
            // 获取当前时间
            Date now = Date.from(Instant.now());
            borrowRecord.setBorrowTime(now);
            // 计算归还时间

            long dueTimeMillis = now.getTime() + TimeUnit.DAYS.toMillis(borrowBookDTO.getBorrowDays());
            Date dueTime = new Date(dueTimeMillis);
            borrowRecord.setDueReturnTime(dueTime);
            borrowRecord.setBorrowStatus(0); // 0表示借阅中

            // 保存借阅记录
            boolean saveResult = this.save(borrowRecord);
            if (saveResult) {
                // 更新图书副本状态为借出
                bookCopy.setBookCopyStatus(1);
                bookCopyService.updateById(bookCopy);
                return Result.success("借阅成功");
            }
            throw new BusinessException("借阅失败");
        } catch (Exception e) {
            throw new BusinessException("借阅失败：" + e.getMessage());
        }
    }
}




